package dycloud.mabaoguo.User.service;


import dycloud.mabaoguo.User.model.*;
import dycloud.mabaoguo.User.model.roleCambat.CombatRankingData;
import dycloud.mabaoguo.User.model.roleCambat.UserCombatInfo;
import dycloud.mabaoguo.User.model.worldRank.WorldRankPlayerInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Service
@Slf4j
public class UserInfoService {

    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 检查用户是否存在，如果不存在，则插入新的用户信息。
     *
     */
    public Json_UserInfo checkAndInsertUserInfo(Json_UserInfo userInfo) {
        try {
            // 根据 playid 查询是否已经有该用户
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(userInfo.getPlayid()));
            Json_UserInfo existingUserInfo = mongoTemplate.findOne(query, Json_UserInfo.class);

            // 如果不存在该用户，则插入新用户数据
            if (existingUserInfo == null) {
                mongoTemplate.insert(userInfo);
                log.info("UserService 35 --->existingUserInfo  is  null --<    playid: {}", userInfo.getPlayid());
            } else {
                log.info("UserService 37 --->existingUserInfo not null --<   playid: {}", userInfo.getPlayid());
            }

            return userInfo;
        } catch (Exception e) {
            log.error("UserService 42 ，playid: {}", userInfo.getPlayid(), e);
            return null;  // 可以根据需求返回错误信息或抛出异常
        }
    }


    /**
     * 获取用户数据，如果不存在，则初始化并插入该玩家数据。
     *
     * @param playid 用户的唯一标识
     * @return 用户数据
     */
    public Json_UserDataInfo getUserDataInfo(String playid) {
        try {
            // 查询用户数据
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(playid));
            Json_UserDataInfo userDataInfo = mongoTemplate.findOne(query, Json_UserDataInfo.class);

            // 如果用户数据不存在，则初始化并插入
            if (userDataInfo == null) {
                userDataInfo = new Json_UserDataInfo();
                userDataInfo.setPlayid(playid);
                userDataInfo.setWinCount(0);
                userDataInfo.setWorldRank(0);

                mongoTemplate.insert(userDataInfo);
                log.info("UserService 69 --->userDataInfo  is null <----，playid: {}", playid);
            }else {
                log.info("UserService 71 --->userDataInfo  not  null <----，playid: {}", userDataInfo.getPlayid());
                log.info("UserService 72 --->userDataInfo  not  null <----，winCount: {}", userDataInfo.getWinCount());
            }
            log.info("UserService 74 --->userDataInfo<----，winCount: {}", userDataInfo.getWinCount());
            return userDataInfo;
        } catch (Exception e) {
            log.error("UserService 77 --->userDataInfo error <----");
            return null;  // 可以根据需求返回错误信息或抛出异常
        }
    }

    /**
     * 设置用户的连胜点。
     * 如果用户数据不存在，则初始化并插入该用户数据。
     *
     * @param playid   用户的唯一标识
     * @param winCount 连胜点数
     */
    public boolean setUserWinCount(String playid, long winCount) {
        try {
            // 查询用户数据
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(playid));
            Json_UserDataInfo userDataInfo = mongoTemplate.findOne(query, Json_UserDataInfo.class);

            // 如果用户数据存在，更新连胜点
            if (userDataInfo != null) {
                userDataInfo.setWinCount(winCount);
                mongoTemplate.save(userDataInfo);  // 更新用户数据
                log.info("100:Update  playid{}  ---> winCount:{} <---", playid, winCount);

            } else {
                // 如果用户数据不存在，初始化并插入
                userDataInfo = new Json_UserDataInfo();
                userDataInfo.setPlayid(playid);
                userDataInfo.setWinCount(winCount);  // 设置初始连胜点
                userDataInfo.setWorldRank(0);  // 设置默认排名为 0（如果需要）
                mongoTemplate.insert(userDataInfo);  // 插入新的用户数据
                log.info("109:user is null  playid{}  ---> winCount:{} <---", playid, winCount);

            }
            return true;
        } catch (Exception e) {
            log.error("set  winCount  error", playid, e);
            return false;
        }
    }

    /**
     * 累加用户的连胜点。
     * 如果用户数据不存在，则初始化并插入该用户数据。
     *
     * @param playid   用户的唯一标识
     * @param additionalWinCount 需要累加的连胜点数
     */
    public boolean addWinCount(String playid, long additionalWinCount) {
        try {
            // 查询用户数据
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(playid));
            Json_UserDataInfo userDataInfo = mongoTemplate.findOne(query, Json_UserDataInfo.class);

            // 如果用户数据存在，累加连胜点
            if (userDataInfo != null) {
                long newWinCount = userDataInfo.getWinCount() + additionalWinCount;
                userDataInfo.setWinCount(newWinCount);
                mongoTemplate.save(userDataInfo);  // 更新用户数据
                log.info("Updated winCount for playid {} to {}", playid, newWinCount);
            } else {
                // 如果用户数据不存在，初始化并插入
                userDataInfo = new Json_UserDataInfo();
                userDataInfo.setPlayid(playid);
                userDataInfo.setWinCount(additionalWinCount);  // 设置初始连胜点为提供的额外点数
                userDataInfo.setWorldRank(0);  // 设置默认排名为 0（如果需要）
                mongoTemplate.insert(userDataInfo);  // 插入新的用户数据
                log.info("Inserted new user with playid {} and initial winCount {}", playid, additionalWinCount);
            }
            return true;
        } catch (Exception e) {
            log.error("Error adding winCount for playid {}: {}", playid, e.getMessage(), e);
            return false;
        }
    }


    public long getUserWinCount(String playid) {
        try {
            // 查询用户数据
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(playid));
            Json_UserDataInfo userDataInfo = mongoTemplate.findOne(query, Json_UserDataInfo.class);

            // 如果用户数据存在，返回连胜点
            if (userDataInfo != null) {
                log.info("128: return playid{}  --->winCount:{}<----", playid, userDataInfo.getWinCount());
                return userDataInfo.getWinCount();
            } else {
                // 用户数据不存在，返回 0 或者其他默认值
                log.warn("132:userDataInfo is null   playid -->{}", playid);
                return 0;
            }
        } catch (Exception e) {
            log.error("getWinCOunt  error   playID:{}", playid, e);
            return 0;  // 返回默认值或处理错误
        }
    }


    /**
     * 重新计算世界排名。
     * 根据玩家的胜利点数对所有玩家进行重新排序并更新排名。
     */
    public void recalculateWorldRank() {
        try {
            // 获取所有玩家数据
            List<Json_UserDataInfo> allUsers = mongoTemplate.findAll(Json_UserDataInfo.class);

            // 根据胜利点数降序排序
            allUsers.sort(Comparator.comparingLong(Json_UserDataInfo::getWinCount).reversed());

            // 更新世界排名
            for (int i = 0; i < allUsers.size(); i++) {
                Json_UserDataInfo userData = allUsers.get(i);
                userData.setWorldRank(i + 1); // 排名从 1 开始
                mongoTemplate.save(userData);
            }

            log.info("164: WorldRank Update Success ，Count  --> {} <-- User Join Game", allUsers.size());
        } catch (Exception e) {
            log.error("166: WorldRank  Update   Error: {}", e.getMessage(), e);
        }
    }

    /**
     * 获取当前世界排名的所有玩家信息。
     * 每次获取前确保世界排名是最新的。
     * @return 世界排名的玩家信息列表
     */
    public List<Json_UserDataInfo> getCurrentWorldRank() {
        try {
            // 重新计算世界排名
            recalculateWorldRank();

            // 获取所有玩家数据并按排名升序返回
            List<Json_UserDataInfo> allUsers = mongoTemplate.findAll(Json_UserDataInfo.class);
            allUsers.sort(Comparator.comparingInt(Json_UserDataInfo::getWorldRank));

            log.info("184: Get WorldRank Success ，Count  --> {} <-- User Join Game", allUsers.size());
            return allUsers;
        } catch (Exception e) {
            log.error("187: Get WorldRank Failure   Error: {}", e.getMessage(), e);
            return null;
        }
    }



    // 更新攻击方的战力榜排名
    public void updateAtkCombatRank() {
        // 获取攻击方所有战力数据
        List<Json_Atk_Combat> atkCombatList = mongoTemplate.findAll(Json_Atk_Combat.class);

        // 排序：根据战力降序
        atkCombatList.sort(Comparator.comparingLong(Json_Atk_Combat::getCombat).reversed());

        // 更新排名
        int rank = 1;
        for (Json_Atk_Combat combat : atkCombatList) {
            combat.setRoleRank(rank++);
            mongoTemplate.save(combat);
        }
    }

    // 更新防守方的战力榜排名
    public void updateDefCombatRank() {
        // 获取防守方所有战力数据
        List<Json_Def_Combat> defCombatList = mongoTemplate.findAll(Json_Def_Combat.class);

        // 排序：根据战力降序
        defCombatList.sort(Comparator.comparingLong(Json_Def_Combat::getCombat).reversed());

        // 更新排名
        int rank = 1;
        for (Json_Def_Combat combat : defCombatList) {
            combat.setRoleRank(rank++);
            mongoTemplate.save(combat);
        }
    }

    //累加 战力
    public void updateOrInsertCombat(String playid, long additionalCombat, Class<?> combatClass) {
        Query query = new Query();
        query.addCriteria(Criteria.where("playid").is(playid));
        Object combatData = mongoTemplate.findOne(query, combatClass);

        if (combatData != null) {
            if (combatClass.equals(Json_Atk_Combat.class)) {
                Json_Atk_Combat combat = (Json_Atk_Combat) combatData;
                combat.setCombat(combat.getCombat() + additionalCombat);
                mongoTemplate.save(combat);
            } else if (combatClass.equals(Json_Def_Combat.class)) {
                Json_Def_Combat combat = (Json_Def_Combat) combatData;
                combat.setCombat(combat.getCombat() + additionalCombat);
                mongoTemplate.save(combat);
            }
        } else {
            if (combatClass.equals(Json_Atk_Combat.class)) {
                Json_Atk_Combat newCombat = new Json_Atk_Combat();
                newCombat.setPlayid(playid);
                newCombat.setCombat(additionalCombat);
                newCombat.setRoleRank(0);  // 初始排名设置为 0，需要重新计算
                mongoTemplate.insert(newCombat);
            } else if (combatClass.equals(Json_Def_Combat.class)) {
                Json_Def_Combat newCombat = new Json_Def_Combat();
                newCombat.setPlayid(playid);
                newCombat.setCombat(additionalCombat);
                newCombat.setRoleRank(0);  // 初始排名设置为 0，需要重新计算
                mongoTemplate.insert(newCombat);
            }
        }
    }


    /**
     * 获取指定玩家的当前世界排名。
     *
     * @param playid 用户的唯一标识
     * @return 用户的世界排名或者返回错误信息如果用户不存在
     */
    public int getCurrentWorldRankByPlayer(String playid) {
        try {
            // 查询指定的玩家
            Query query = new Query();
            query.addCriteria(Criteria.where("playid").is(playid));
            Json_UserDataInfo userData = mongoTemplate.findOne(query, Json_UserDataInfo.class);

            if (userData != null) {
                log.info("Found world rank for playid {}: {}", playid, userData.getWorldRank());
                return userData.getWorldRank();
            } else {
                log.warn("No user found with playid {}", playid);
                return -1;  // 可以返回-1或者抛出一个异常，取决于你的业务逻辑
            }
        } catch (Exception e) {
            log.error("Error fetching world rank for playid {}: {}", playid, e.getMessage(), e);
            return -1;  // 出错时返回-1或者根据业务需要调整
        }
    }
    public CombatRankingData getCombatRankingData() {
        CombatRankingData combatRankingData = new CombatRankingData();

        // 获取攻击方战力数据
        List<Json_Atk_Combat> atkCombatRanks = mongoTemplate.findAll(Json_Atk_Combat.class);

        // 排序：根据战力降序排序
        atkCombatRanks.sort(Comparator.comparingLong(Json_Atk_Combat::getCombat).reversed());

        // 限制攻击方数据最多为前50名（如果不足50名，则取实际数据数量）
        int atkLimit = Math.min(50, atkCombatRanks.size());
        List<Json_Atk_Combat> topAtkCombatRanks = atkCombatRanks.subList(0, atkLimit);

        List<UserCombatInfo> atkCombatInfos = new ArrayList<>();
        // 填充攻击方数据，查询头像和昵称
        for (Json_Atk_Combat atk : topAtkCombatRanks) {
            Json_UserInfo userInfo = mongoTemplate.findById(atk.getPlayid(), Json_UserInfo.class);
            if (userInfo != null) {
                UserCombatInfo userCombatInfo = new UserCombatInfo();
                userCombatInfo.setPlayid(atk.getPlayid());
                userCombatInfo.setCombat(atk.getCombat());
                userCombatInfo.setRoleRank(atk.getRoleRank());
                userCombatInfo.setHeadurl(userInfo.getHeadurl());
                userCombatInfo.setNickname(userInfo.getNickname());

                atkCombatInfos.add(userCombatInfo);
            }
        }
        combatRankingData.setAtkCombatRanks(atkCombatInfos);

        // 获取防守方战力数据
        List<Json_Def_Combat> defCombatRanks = mongoTemplate.findAll(Json_Def_Combat.class);

        // 排序：根据战力降序排序
        defCombatRanks.sort(Comparator.comparingLong(Json_Def_Combat::getCombat).reversed());

        // 限制防守方数据最多为前50名（如果不足50名，则取实际数据数量）
        int defLimit = Math.min(50, defCombatRanks.size());
        List<Json_Def_Combat> topDefCombatRanks = defCombatRanks.subList(0, defLimit);

        List<UserCombatInfo> defCombatInfos = new ArrayList<>();
        // 塁防守方数据，查询头像和昵称
        for (Json_Def_Combat def : topDefCombatRanks) {
            Json_UserInfo userInfo = mongoTemplate.findById(def.getPlayid(), Json_UserInfo.class);
            if (userInfo != null) {
                UserCombatInfo userCombatInfo = new UserCombatInfo();
                userCombatInfo.setPlayid(def.getPlayid());
                userCombatInfo.setCombat(def.getCombat());
                userCombatInfo.setRoleRank(def.getRoleRank());
                userCombatInfo.setHeadurl(userInfo.getHeadurl());
                userCombatInfo.setNickname(userInfo.getNickname());

                defCombatInfos.add(userCombatInfo);
            }
        }
        combatRankingData.setDefCombatRanks(defCombatInfos);

        return combatRankingData;
    }

    public List<WorldRankPlayerInfo> getWorldRank() {
        try {
            // 重新计算世界排名
            recalculateWorldRank();

            // 获取所有玩家的世界排名数据
            List<Json_UserDataInfo> allUsers = mongoTemplate.findAll(Json_UserDataInfo.class);
            allUsers.sort(Comparator.comparingInt(Json_UserDataInfo::getWorldRank));

            // 限制最多获取前100名（不足100名则取实际数量）
            int limit = Math.min(100, allUsers.size());
            List<Json_UserDataInfo> topUsers = allUsers.subList(0, limit);

            // 创建一个新的列表来存储完整的玩家信息
            List<WorldRankPlayerInfo> worldRankPlayerInfoList = new ArrayList<>();

            // 遍历每个玩家，填充更多信息
            for (Json_UserDataInfo user : topUsers) {
                // 查找玩家的详细信息（如头像和昵称）
                Json_UserInfo userInfo = mongoTemplate.findById(user.getPlayid(), Json_UserInfo.class);
                if (userInfo != null) {
                    // 创建一个新的对象并填充数据
                    WorldRankPlayerInfo playerInfo = new WorldRankPlayerInfo();
                    playerInfo.setPlayid(user.getPlayid());
                    playerInfo.setWinCount(user.getWinCount());
                    playerInfo.setWorldRank(user.getWorldRank());
                    playerInfo.setHeadurl(userInfo.getHeadurl());
                    playerInfo.setNickname(userInfo.getNickname());

                    // 将玩家信息添加到列表中
                    worldRankPlayerInfoList.add(playerInfo);
                }
            }

            log.info("184: Get WorldRank Success ，Count  --> {} <-- User Join Game", worldRankPlayerInfoList.size());
            return worldRankPlayerInfoList;

        } catch (Exception e) {
            log.error("187: Get WorldRank Failure   Error: {}", e.getMessage(), e);
            return null;
        }
    }


    /**
     * 检查 MongoDB 数据库连接
     * @return true 如果数据库连接成功，false 如果连接失败
     */
    public boolean checkDatabaseConnection() {
        try {
            // 使用 MongoTemplate 执行简单查询来检查数据库连接
            mongoTemplate.executeCommand("{ping: 1}");  // 执行一个 ping 命令
            return true;  // 如果没有异常，表示数据库连接正常
        } catch (Exception e) {
            log.error("Database connection failed: {}", e.getMessage());
            return false;  // 如果发生异常，表示数据库连接失败
        }
    }


}
